home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / doom / quake3.zip / RANDOM.ZIP / ITEMS.QC < prev    next >
Text File  |  1996-08-07  |  30KB  |  1,410 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. float(entity e) CheckEntity =
  7. {
  8.     if (e.classname == "weapon_nailgun")
  9.         return TRUE;
  10.     else if (e.classname == "weapon_supernailgun")
  11.         return TRUE;
  12.     else if (e.classname == "weapon_supershotgun")
  13.         return TRUE;
  14.     else if (e.classname == "weapon_rocketlauncher")
  15.         return TRUE;
  16.     else if (e.classname == "weapon_grenadelauncher")
  17.         return TRUE;
  18.     else if (e.classname == "weapon_lightning")
  19.         return TRUE;
  20.     else if (e.classname == "item_cells")
  21.         return TRUE;
  22.     else if (e.classname == "item_spikes")
  23.         return TRUE;
  24.     else if (e.classname == "item_shells")
  25.         return TRUE;
  26.     else if (e.classname == "item_rockets")
  27.         return TRUE;
  28.     else if (e.classname == "item_health")
  29.         return TRUE;
  30.     else if (e.classname == "item_artifact_invulnerability")
  31.         return TRUE;
  32.     else if (e.classname == "item_artifact_invisibility")
  33.         return TRUE;
  34.     else if (e.classname == "item_artifact_envirosuit")
  35.         return TRUE;
  36.     else if (e.classname == "item_artifact_super_damage")
  37.         return TRUE;
  38.     else if (e.classname == "item_armor1")
  39.         return TRUE;
  40.     else if (e.classname == "item_armor2")
  41.         return TRUE;
  42.     else if (e.classname == "item_armor3")
  43.         return TRUE;
  44.     return FALSE;
  45. };
  46.  
  47. void() SUB_regen =
  48. {
  49.  
  50.     local vector vTemp;
  51.     local float fItemCount;
  52.     local entity eTemp;
  53.  
  54.     self.model = self.mdl;        // restore original model
  55.     self.solid = SOLID_TRIGGER;    // allow it to be touched again
  56.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);    // play respawn sound
  57.  
  58.     fItemCount=random()*20;
  59.  
  60.     eTemp=findradius(self.origin,10000);
  61.  
  62.     while (fItemCount>0)
  63.         {
  64.         eTemp=eTemp.chain;
  65.         fItemCount=fItemCount - 1;
  66.         if (!eTemp.chain)
  67.             {
  68.             setorigin (self,self.origin);
  69.             return;
  70.             }
  71.         }
  72.  
  73.     while (CheckEntity(eTemp)!=TRUE)
  74.         eTemp=eTemp.chain;
  75.  
  76.     vTemp=eTemp.origin;
  77.  
  78.     setorigin (eTemp,self.origin);
  79.     
  80.     setorigin (self, vTemp);
  81. };
  82.  
  83.  
  84.  
  85. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  86. prints a warning message when spawned
  87. */
  88. void() noclass =
  89. {
  90.     dprint ("noclass spawned at");
  91.     dprint (vtos(self.origin));
  92.     dprint ("\n");
  93.     remove (self);
  94. };
  95.  
  96.  
  97.  
  98. /*
  99. ============
  100. PlaceItem
  101.  
  102. plants the object on the floor
  103. ============
  104. */
  105. void() PlaceItem =
  106. {
  107.     local float    oldz;
  108.  
  109.     self.mdl = self.model;        // so it can be restored on respawn
  110.     self.flags = FL_ITEM;        // make extra wide
  111.     self.solid = SOLID_TRIGGER;
  112.     self.movetype = MOVETYPE_TOSS;    
  113.     self.velocity = '0 0 0';
  114.     self.origin_z = self.origin_z + 6;
  115.     oldz = self.origin_z;
  116.     if (!droptofloor())
  117.     {
  118.         dprint ("Bonus item fell out of level at ");
  119.         dprint (vtos(self.origin));
  120.         dprint ("\n");
  121.         remove(self);
  122.         return;
  123.     }
  124. };
  125.  
  126. /*
  127. ============
  128. StartItem
  129.  
  130. Sets the clipping size and plants the object on the floor
  131. ============
  132. */
  133. void() StartItem =
  134. {
  135.     self.nextthink = time + 0.2;    // items start after other solids
  136.     self.think = PlaceItem;
  137. };
  138.  
  139. /*
  140. =========================================================================
  141.  
  142. HEALTH BOX
  143.  
  144. =========================================================================
  145. */
  146. //
  147. // T_Heal: add health to an entity, limiting health to max_health
  148. // "ignore" will ignore max_health limit
  149. //
  150. float (entity e, float healamount, float ignore) T_Heal =
  151. {
  152.     if (e.health <= 0)
  153.         return 0;
  154.     if ((!ignore) && (e.health >= other.max_health))
  155.         return 0;
  156.     healamount = ceil(healamount);
  157.  
  158.     e.health = e.health + healamount;
  159.     if ((!ignore) && (e.health >= other.max_health))
  160.         e.health = other.max_health;
  161.         
  162.     if (e.health > 250)
  163.         e.health = 250;
  164.     return 1;
  165. };
  166.  
  167. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  168. Health box. Normally gives 25 points.
  169. Rotten box heals 5-10 points,
  170. megahealth will add 100 health, then 
  171. rot you down to your maximum health limit, 
  172. one point per second.
  173. */
  174.  
  175. float    H_ROTTEN = 1;
  176. float    H_MEGA = 2;
  177. .float    healamount, healtype;
  178. void() health_touch;
  179. void() item_megahealth_rot;
  180.  
  181. void() item_health =
  182. {    
  183.     self.touch = health_touch;
  184.  
  185.     if (self.spawnflags & H_ROTTEN)
  186.     {
  187.         precache_model("maps/b_bh10.bsp");
  188.  
  189.         precache_sound("items/r_item1.wav");
  190.         setmodel(self, "maps/b_bh10.bsp");
  191.         self.noise = "items/r_item1.wav";
  192.         self.healamount = 15;
  193.         self.healtype = 0;
  194.     }
  195.     else
  196.     if (self.spawnflags & H_MEGA)
  197.     {
  198.         precache_model("maps/b_bh100.bsp");
  199.         precache_sound("items/r_item2.wav");
  200.         setmodel(self, "maps/b_bh100.bsp");
  201.         self.noise = "items/r_item2.wav";
  202.         self.healamount = 100;
  203.         self.healtype = 2;
  204.     }
  205.     else
  206.     {
  207.         precache_model("maps/b_bh25.bsp");
  208.         precache_sound("items/health1.wav");
  209.         setmodel(self, "maps/b_bh25.bsp");
  210.         self.noise = "items/health1.wav";
  211.         self.healamount = 25;
  212.         self.healtype = 1;
  213.     }
  214.     setsize (self, '0 0 0', '32 32 56');
  215.     StartItem ();
  216. };
  217.  
  218.  
  219. void() health_touch =
  220. {
  221.     local    float amount;
  222.     local    string    s;
  223.     
  224.     if (other.classname != "player")
  225.         return;
  226.     
  227.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  228.     {
  229.         if (other.health >= 250)
  230.             return;
  231.         if (!T_Heal(other, self.healamount, 1))
  232.             return;
  233.     }
  234.     else
  235.     {
  236.         if (!T_Heal(other, self.healamount, 0))
  237.             return;
  238.     }
  239.     
  240.     sprint(other, "You receive ");
  241.     s = ftos(self.healamount);
  242.     sprint(other, s);
  243.     sprint(other, " health\n");
  244.     
  245. // health touch sound
  246.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  247.  
  248.     stuffcmd (other, "bf\n");
  249.     
  250.     self.model = string_null;
  251.     self.solid = SOLID_NOT;
  252.  
  253.     // Megahealth = rot down the player's super health
  254.     if (self.healtype == 2)
  255.     {
  256.         other.items = other.items | IT_SUPERHEALTH;
  257.         self.nextthink = time + 5;
  258.         self.think = item_megahealth_rot;
  259.         self.owner = other;
  260.     }
  261.     else
  262.     {
  263.         if (deathmatch != 2)        // deathmatch 2 is the silly old rules
  264.         {
  265.             if (deathmatch)
  266.                 self.nextthink = time + 20;
  267.             self.think = SUB_regen;
  268.         }
  269.     }
  270.     
  271.     activator = other;
  272.     SUB_UseTargets();                // fire all targets / killtargets
  273. };    
  274.  
  275. void() item_megahealth_rot =
  276. {
  277.     other = self.owner;
  278.     
  279.     if (other.health > other.max_health)
  280.     {
  281.         other.health = other.health - 1;
  282.         self.nextthink = time + 1;
  283.         return;
  284.     }
  285.  
  286. // it is possible for a player to die and respawn between rots, so don't
  287. // just blindly subtract the flag off
  288.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  289.     
  290.     if (deathmatch == 1)    // deathmatch 2 is silly old rules
  291.     {
  292.         self.nextthink = time + 20;
  293.         self.think = SUB_regen;
  294.     }
  295. };
  296.  
  297. /*
  298. ===============================================================================
  299.  
  300. ARMOR
  301.  
  302. ===============================================================================
  303. */
  304.  
  305. void() armor_touch;
  306.  
  307. void() armor_touch =
  308. {
  309.     local    float    type, value, bit;
  310.     
  311.     if (other.health <= 0)
  312.         return;
  313.     if (other.classname != "player")
  314.         return;
  315.  
  316.     if (self.classname == "item_armor1")
  317.     {
  318.         type = 0.3;
  319.         value = 100;
  320.         bit = IT_ARMOR1;
  321.     }
  322.     if (self.classname == "item_armor2")
  323.     {
  324.         type = 0.6;
  325.         value = 150;
  326.         bit = IT_ARMOR2;
  327.     }
  328.     if (self.classname == "item_armorInv")
  329.     {
  330.         type = 0.8;
  331.         value = 200;
  332.         bit = IT_ARMOR3;
  333.     }
  334.     if (other.armortype*other.armorvalue >= type*value)
  335.         return;
  336.         
  337.     other.armortype = type;
  338.     other.armorvalue = value;
  339.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  340.  
  341.     self.solid = SOLID_NOT;
  342.     self.model = string_null;
  343.     if (deathmatch == 1)
  344.         self.nextthink = time + 20;
  345.     self.think = SUB_regen;
  346.  
  347.     sprint(other, "You got armor\n");
  348. // armor touch sound
  349.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  350.     stuffcmd (other, "bf\n");
  351.     
  352.     activator = other;
  353.     SUB_UseTargets();                // fire all targets / killtargets
  354. };
  355.  
  356.  
  357. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  358. */
  359.  
  360. void() item_armor1 =
  361. {
  362.     self.touch = armor_touch;
  363.     precache_model ("progs/armor.mdl");
  364.     setmodel (self, "progs/armor.mdl");
  365.     self.skin = 0;
  366.     setsize (self, '-16 -16 0', '16 16 56');
  367.     StartItem ();
  368. };
  369.  
  370. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  371. */
  372.  
  373. void() item_armor2 =
  374. {
  375.     self.touch = armor_touch;
  376.     precache_model ("progs/armor.mdl");
  377.     setmodel (self, "progs/armor.mdl");
  378.     self.skin = 1;
  379.     setsize (self, '-16 -16 0', '16 16 56');
  380.     StartItem ();
  381. };
  382.  
  383. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  384. */
  385.  
  386. void() item_armorInv =
  387. {
  388.     self.touch = armor_touch;
  389.     precache_model ("progs/armor.mdl");
  390.     setmodel (self, "progs/armor.mdl");
  391.     self.skin = 2;
  392.     setsize (self, '-16 -16 0', '16 16 56');
  393.     StartItem ();
  394. };
  395.  
  396. /*
  397. ===============================================================================
  398.  
  399. WEAPONS
  400.  
  401. ===============================================================================
  402. */
  403.  
  404. void() bound_other_ammo =
  405. {
  406.     if (other.ammo_shells > 100)
  407.         other.ammo_shells = 100;
  408.     if (other.ammo_nails > 200)
  409.         other.ammo_nails = 200;
  410.     if (other.ammo_rockets > 100)
  411.         other.ammo_rockets = 100;        
  412.     if (other.ammo_cells > 100)
  413.         other.ammo_cells = 100;        
  414. };
  415.  
  416.  
  417. float(float w) RankForWeapon =
  418. {
  419.     if (w == IT_LIGHTNING)
  420.         return 1;
  421.     if (w == IT_ROCKET_LAUNCHER)
  422.         return 2;
  423.     if (w == IT_SUPER_NAILGUN)
  424.         return 3;
  425.     if (w == IT_GRENADE_LAUNCHER)
  426.         return 4;
  427.     if (w == IT_SUPER_SHOTGUN)
  428.         return 5;
  429.     if (w == IT_NAILGUN)
  430.         return 6;
  431.     return 7;
  432. };
  433.  
  434. /*
  435. =============
  436. Deathmatch_Weapon
  437.  
  438. Deathmatch weapon change rules for picking up a weapon
  439.  
  440. .float        ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  441. =============
  442. */
  443. void(float old, float new) Deathmatch_Weapon =
  444. {
  445.     local float or, nr;
  446.  
  447. // change self.weapon if desired
  448.     or = RankForWeapon (self.weapon);
  449.     nr = RankForWeapon (new);
  450.     if ( nr < or )
  451.         self.weapon = new;
  452. };
  453.  
  454. /*
  455. =============
  456. weapon_touch
  457. =============
  458. */
  459. float() W_BestWeapon;
  460.  
  461. void() weapon_touch =
  462. {
  463.     local    float    hadammo, best, new, old;
  464.     local    entity    stemp;
  465.     local    float    leave;
  466.  
  467.     if (!(other.flags & FL_CLIENT))
  468.         return;
  469.  
  470. // if the player was using his best weapon, change up to the new one if better        
  471.     stemp = self;
  472.     self = other;
  473.     best = W_BestWeapon();
  474.     self = stemp;
  475.  
  476.     if (deathmatch == 2 || coop)
  477.         leave = 1;
  478.     else
  479.         leave = 0;
  480.     
  481.     if (self.classname == "weapon_nailgun")
  482.     {
  483.         if (leave && (other.items & IT_NAILGUN) )
  484.             return;
  485.         hadammo = other.ammo_nails;            
  486.         new = IT_NAILGUN;
  487.         other.ammo_nails = other.ammo_nails + 30;
  488.     }
  489.     else if (self.classname == "weapon_supernailgun")
  490.     {
  491.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  492.             return;
  493.         hadammo = other.ammo_rockets;            
  494.         new = IT_SUPER_NAILGUN;
  495.         other.ammo_nails = other.ammo_nails + 30;
  496.     }
  497.     else if (self.classname == "weapon_supershotgun")
  498.     {
  499.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  500.             return;
  501.         hadammo = other.ammo_rockets;            
  502.         new = IT_SUPER_SHOTGUN;
  503.         other.ammo_shells = other.ammo_shells + 5;
  504.     }
  505.     else if (self.classname == "weapon_rocketlauncher")
  506.     {
  507.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  508.             return;
  509.         hadammo = other.ammo_rockets;            
  510.         new = IT_ROCKET_LAUNCHER;
  511.         other.ammo_rockets = other.ammo_rockets + 5;
  512.     }
  513.     else if (self.classname == "weapon_grenadelauncher")
  514.     {
  515.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  516.             return;
  517.         hadammo = other.ammo_rockets;            
  518.         new = IT_GRENADE_LAUNCHER;
  519.         other.ammo_rockets = other.ammo_rockets + 5;
  520.     }
  521.     else if (self.classname == "weapon_lightning")
  522.     {
  523.         if (leave && (other.items & IT_LIGHTNING) )
  524.             return;
  525.         hadammo = other.ammo_rockets;            
  526.         new = IT_LIGHTNING;
  527.         other.ammo_cells = other.ammo_cells + 15;
  528.     }
  529.     else
  530.         objerror ("weapon_touch: unknown classname");
  531.  
  532.     sprint (other, "You got the ");
  533.     sprint (other, self.netname);
  534.     sprint (other, "\n");
  535. // weapon touch sound
  536.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  537.     stuffcmd (other, "bf\n");
  538.  
  539.     bound_other_ammo ();
  540.  
  541. // change to the weapon
  542.     old = other.items;
  543.     other.items = other.items | new;
  544.     
  545.     stemp = self;
  546.     self = other;
  547.  
  548.     if (!deathmatch)
  549.         self.weapon = new;
  550.     else
  551.         Deathmatch_Weapon (old, new);
  552.  
  553.     W_SetCurrentAmmo();
  554.  
  555.     self = stemp;
  556.  
  557.     if (leave)
  558.         return;
  559.  
  560. // remove it in single player, or setup for respawning in deathmatch
  561.     self.model = string_null;
  562.     self.solid = SOLID_NOT;
  563.     if (deathmatch == 1)
  564.         self.nextthink = time + 30;
  565.     self.think = SUB_regen;
  566.     
  567.     activator = other;
  568.     SUB_UseTargets();                // fire all targets / killtargets
  569. };
  570.  
  571.  
  572. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  573. */
  574.  
  575. void() weapon_supershotgun =
  576. {
  577.     precache_model ("progs/g_shot.mdl");
  578.     setmodel (self, "progs/g_shot.mdl");
  579.     self.weapon = IT_SUPER_SHOTGUN;
  580.     self.netname = "Double-barrelled Shotgun";
  581.     self.touch = weapon_touch;
  582.     setsize (self, '-16 -16 0', '16 16 56');
  583.     StartItem ();
  584. };
  585.  
  586. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  587. */
  588.  
  589. void() weapon_nailgun =
  590. {
  591.     precache_model ("progs/g_nail.mdl");
  592.     setmodel (self, "progs/g_nail.mdl");
  593.     self.weapon = IT_NAILGUN;
  594.     self.netname = "nailgun";
  595.     self.touch = weapon_touch;
  596.     setsize (self, '-16 -16 0', '16 16 56');
  597.     StartItem ();
  598. };
  599.  
  600. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  601. */
  602.  
  603. void() weapon_supernailgun =
  604. {
  605.     precache_model ("progs/g_nail2.mdl");
  606.     setmodel (self, "progs/g_nail2.mdl");
  607.     self.weapon = IT_SUPER_NAILGUN;
  608.     self.netname = "Super Nailgun";
  609.     self.touch = weapon_touch;
  610.     setsize (self, '-16 -16 0', '16 16 56');
  611.     StartItem ();
  612. };
  613.  
  614. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  615. */
  616.  
  617. void() weapon_grenadelauncher =
  618. {
  619.     precache_model ("progs/g_rock.mdl");
  620.     setmodel (self, "progs/g_rock.mdl");
  621.     self.weapon = 3;
  622.     self.netname = "Grenade Launcher";
  623.     self.touch = weapon_touch;
  624.     setsize (self, '-16 -16 0', '16 16 56');
  625.     StartItem ();
  626. };
  627.  
  628. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  629. */
  630.  
  631. void() weapon_rocketlauncher =
  632. {
  633.     precache_model ("progs/g_rock2.mdl");
  634.     setmodel (self, "progs/g_rock2.mdl");
  635.     self.weapon = 3;
  636.     self.netname = "Rocket Launcher";
  637.     self.touch = weapon_touch;
  638.     setsize (self, '-16 -16 0', '16 16 56');
  639.     StartItem ();
  640. };
  641.  
  642.  
  643. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  644. */
  645.  
  646. void() weapon_lightning =
  647. {
  648.     precache_model ("progs/g_light.mdl");
  649.     setmodel (self, "progs/g_light.mdl");
  650.     self.weapon = 3;
  651.     self.netname = "Thunderbolt";
  652.     self.touch = weapon_touch;
  653.     setsize (self, '-16 -16 0', '16 16 56');
  654.     StartItem ();
  655. };
  656.  
  657.  
  658. /*
  659. ===============================================================================
  660.  
  661. AMMO
  662.  
  663. ===============================================================================
  664. */
  665.  
  666. void() ammo_touch =
  667. {
  668. local entity    stemp;
  669. local float        best;
  670.  
  671.     if (other.classname != "player")
  672.         return;
  673.     if (other.health <= 0)
  674.         return;
  675.  
  676. // if the player was using his best weapon, change up to the new one if better        
  677.     stemp = self;
  678.     self = other;
  679.     best = W_BestWeapon();
  680.     self = stemp;
  681.  
  682.  
  683. // shotgun
  684.     if (self.weapon == 1)
  685.     {
  686.         if (other.ammo_shells >= 100)
  687.             return;
  688.         other.ammo_shells = other.ammo_shells + self.aflag;
  689.     }
  690.  
  691. // spikes
  692.     if (self.weapon == 2)
  693.     {
  694.         if (other.ammo_nails >= 200)
  695.             return;
  696.         other.ammo_nails = other.ammo_nails + self.aflag;
  697.     }
  698.  
  699. //    rockets
  700.     if (self.weapon == 3)
  701.     {
  702.         if (other.ammo_rockets >= 100)
  703.             return;
  704.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  705.     }
  706.  
  707. //    cells
  708.     if (self.weapon == 4)
  709.     {
  710.         if (other.ammo_cells >= 200)
  711.             return;
  712.         other.ammo_cells = other.ammo_cells + self.aflag;
  713.     }
  714.  
  715.     bound_other_ammo ();
  716.     
  717.     sprint (other, "You got the ");
  718.     sprint (other, self.netname);
  719.     sprint (other, "\n");
  720. // ammo touch sound
  721.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  722.     stuffcmd (other, "bf\n");
  723.  
  724. // change to a better weapon if appropriate
  725.  
  726.     if ( other.weapon == best )
  727.     {
  728.         stemp = self;
  729.         self = other;
  730.         self.weapon = W_BestWeapon();
  731.         W_SetCurrentAmmo ();
  732.         self = stemp;
  733.     }
  734.  
  735. // if changed current ammo, update it
  736.     stemp = self;
  737.     self = other;
  738.     W_SetCurrentAmmo();
  739.     self = stemp;
  740.  
  741. // remove it in single player, or setup for respawning in deathmatch
  742.     self.model = string_null;
  743.     self.solid = SOLID_NOT;
  744.     if (deathmatch == 1)
  745.         self.nextthink = time + 30;
  746.     
  747.     self.think = SUB_regen;
  748.  
  749.     activator = other;
  750.     SUB_UseTargets();                // fire all targets / killtargets
  751. };
  752.  
  753.  
  754.  
  755.  
  756. float WEAPON_BIG2 = 1;
  757.  
  758. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  759. */
  760.  
  761. void() item_shells =
  762. {
  763.     self.touch = ammo_touch;
  764.  
  765.     if (self.spawnflags & WEAPON_BIG2)
  766.     {
  767.         precache_model ("maps/b_shell1.bsp");
  768.         setmodel (self, "maps/b_shell1.bsp");
  769.         self.aflag = 40;
  770.     }
  771.     else
  772.     {
  773.         precache_model ("maps/b_shell0.bsp");
  774.         setmodel (self, "maps/b_shell0.bsp");
  775.         self.aflag = 20;
  776.     }
  777.     self.weapon = 1;
  778.     self.netname = "shells";
  779.     setsize (self, '0 0 0', '32 32 56');
  780.     StartItem ();
  781. };
  782.  
  783. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  784. */
  785.  
  786. void() item_spikes =
  787. {
  788.     self.touch = ammo_touch;
  789.  
  790.     if (self.spawnflags & WEAPON_BIG2)
  791.     {
  792.         precache_model ("maps/b_nail1.bsp");
  793.         setmodel (self, "maps/b_nail1.bsp");
  794.         self.aflag = 50;
  795.     }
  796.     else
  797.     {
  798.         precache_model ("maps/b_nail0.bsp");
  799.         setmodel (self, "maps/b_nail0.bsp");
  800.         self.aflag = 25;
  801.     }
  802.     self.weapon = 2;
  803.     self.netname = "nails";
  804.     setsize (self, '0 0 0', '32 32 56');
  805.     StartItem ();
  806. };
  807.  
  808. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  809. */
  810.  
  811. void() item_rockets =
  812. {
  813.     self.touch = ammo_touch;
  814.  
  815.     if (self.spawnflags & WEAPON_BIG2)
  816.     {
  817.         precache_model ("maps/b_rock1.bsp");
  818.         setmodel (self, "maps/b_rock1.bsp");
  819.         self.aflag = 10;
  820.     }
  821.     else
  822.     {
  823.         precache_model ("maps/b_rock0.bsp");
  824.         setmodel (self, "maps/b_rock0.bsp");
  825.         self.aflag = 5;
  826.     }
  827.     self.weapon = 3;
  828.     self.netname = "rockets";
  829.     setsize (self, '0 0 0', '32 32 56');
  830.     StartItem ();
  831. };
  832.  
  833.  
  834. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  835. */
  836.  
  837. void() item_cells =
  838. {
  839.     self.touch = ammo_touch;
  840.  
  841.     if (self.spawnflags & WEAPON_BIG2)
  842.     {
  843.         precache_model ("maps/b_batt1.bsp");
  844.         setmodel (self, "maps/b_batt1.bsp");
  845.         self.aflag = 12;
  846.     }
  847.     else
  848.     {
  849.         precache_model ("maps/b_batt0.bsp");
  850.         setmodel (self, "maps/b_batt0.bsp");
  851.         self.aflag = 6;
  852.     }
  853.     self.weapon = 4;
  854.     self.netname = "cells";
  855.     setsize (self, '0 0 0', '32 32 56');
  856.     StartItem ();
  857. };
  858.  
  859.  
  860. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  861. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  862. */
  863.  
  864. float WEAPON_SHOTGUN = 1;
  865. float WEAPON_ROCKET = 2;
  866. float WEAPON_SPIKES = 4;
  867. float WEAPON_BIG = 8;
  868. void() item_weapon =
  869. {
  870.     self.touch = ammo_touch;
  871.  
  872.     if (self.spawnflags & WEAPON_SHOTGUN)
  873.     {
  874.         if (self.spawnflags & WEAPON_BIG)
  875.         {
  876.             precache_model ("maps/b_shell1.bsp");
  877.             setmodel (self, "maps/b_shell1.bsp");
  878.             self.aflag = 40;
  879.         }
  880.         else
  881.         {
  882.             precache_model ("maps/b_shell0.bsp");
  883.             setmodel (self, "maps/b_shell0.bsp");
  884.             self.aflag = 20;
  885.         }
  886.         self.weapon = 1;
  887.         self.netname = "shells";
  888.     }
  889.  
  890.     if (self.spawnflags & WEAPON_SPIKES)
  891.     {
  892.         if (self.spawnflags & WEAPON_BIG)
  893.         {
  894.             precache_model ("maps/b_nail1.bsp");
  895.             setmodel (self, "maps/b_nail1.bsp");
  896.             self.aflag = 40;
  897.         }
  898.         else
  899.         {
  900.             precache_model ("maps/b_nail0.bsp");
  901.             setmodel (self, "maps/b_nail0.bsp");
  902.             self.aflag = 20;
  903.         }
  904.         self.weapon = 2;
  905.         self.netname = "spikes";
  906.     }
  907.  
  908.     if (self.spawnflags & WEAPON_ROCKET)
  909.     {
  910.         if (self.spawnflags & WEAPON_BIG)
  911.         {
  912.             precache_model ("maps/b_rock1.bsp");
  913.             setmodel (self, "maps/b_rock1.bsp");
  914.             self.aflag = 10;
  915.         }
  916.         else
  917.         {
  918.             precache_model ("maps/b_rock0.bsp");
  919.             setmodel (self, "maps/b_rock0.bsp");
  920.             self.aflag = 5;
  921.         }
  922.         self.weapon = 3;
  923.         self.netname = "rockets";
  924.     }
  925.     
  926.     setsize (self, '0 0 0', '32 32 56');
  927.     StartItem ();
  928. };
  929.  
  930.  
  931. /*
  932. ===============================================================================
  933.  
  934. KEYS
  935.  
  936. ===============================================================================
  937. */
  938.  
  939. void() key_touch =
  940. {
  941. local entity    stemp;
  942. local float        best;
  943.  
  944.     if (other.classname != "player")
  945.         return;
  946.     if (other.health <= 0)
  947.         return;
  948.     if (other.items & self.items)
  949.         return;
  950.  
  951.     sprint (other, "You got the ");
  952.     sprint (other, self.netname);
  953.     sprint (other,"\n");
  954.  
  955.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  956.     stuffcmd (other, "bf\n");
  957.     other.items = other.items | self.items;
  958.  
  959.     if (!coop)
  960.     {    
  961.         self.solid = SOLID_NOT;
  962.         self.model = string_null;
  963.     }
  964.  
  965.     activator = other;
  966.     SUB_UseTargets();                // fire all targets / killtargets
  967. };
  968.  
  969.  
  970. void() key_setsounds =
  971. {
  972.     if (world.worldtype == 0)
  973.     {
  974.         precache_sound ("misc/medkey.wav");
  975.         self.noise = "misc/medkey.wav";
  976.     }
  977.     if (world.worldtype == 1)
  978.     {
  979.         precache_sound ("misc/runekey.wav");
  980.         self.noise = "misc/runekey.wav";
  981.     }
  982.     if (world.worldtype == 2)
  983.     {
  984.         precache_sound2 ("misc/basekey.wav");
  985.         self.noise = "misc/basekey.wav";
  986.     }
  987. };
  988.  
  989. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  990. SILVER key
  991. In order for keys to work
  992. you MUST set your maps
  993. worldtype to one of the
  994. following:
  995. 0: medieval
  996. 1: metal
  997. 2: base
  998. */
  999.  
  1000. void() item_key1 =
  1001. {
  1002.     if (world.worldtype == 0)
  1003.     {
  1004.         precache_model ("progs/w_s_key.mdl");
  1005.         setmodel (self, "progs/w_s_key.mdl");
  1006.         self.netname = "silver key";
  1007.     }
  1008.     else if (world.worldtype == 1)
  1009.     {
  1010.         precache_model ("progs/m_s_key.mdl");
  1011.         setmodel (self, "progs/m_s_key.mdl");
  1012.         self.netname = "silver runekey";
  1013.     }
  1014.     else if (world.worldtype == 2)
  1015.     {
  1016.         precache_model2 ("progs/b_s_key.mdl");
  1017.         setmodel (self, "progs/b_s_key.mdl");
  1018.         self.netname = "silver keycard";
  1019.     }
  1020.     key_setsounds();
  1021.     self.touch = key_touch;
  1022.     self.items = IT_KEY1;
  1023.     setsize (self, '-16 -16 -24', '16 16 32');
  1024.     StartItem ();
  1025. };
  1026.  
  1027. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  1028. GOLD key
  1029. In order for keys to work
  1030. you MUST set your maps
  1031. worldtype to one of the
  1032. following:
  1033. 0: medieval
  1034. 1: metal
  1035. 2: base
  1036. */
  1037.  
  1038. void() item_key2 =
  1039. {
  1040.     if (world.worldtype == 0)
  1041.     {
  1042.         precache_model ("progs/w_g_key.mdl");
  1043.         setmodel (self, "progs/w_g_key.mdl");
  1044.         self.netname = "gold key";
  1045.     }
  1046.     if (world.worldtype == 1)
  1047.     {
  1048.         precache_model ("progs/m_g_key.mdl");
  1049.         setmodel (self, "progs/m_g_key.mdl");
  1050.         self.netname = "gold runekey";
  1051.     }
  1052.     if (world.worldtype == 2)
  1053.     {
  1054.         precache_model2 ("progs/b_g_key.mdl");
  1055.         setmodel (self, "progs/b_g_key.mdl");
  1056.         self.netname = "gold keycard";
  1057.     }
  1058.     key_setsounds();
  1059.     self.touch = key_touch;
  1060.     self.items = IT_KEY2;
  1061.     setsize (self, '-16 -16 -24', '16 16 32');
  1062.     StartItem ();
  1063. };
  1064.  
  1065.  
  1066.  
  1067. /*
  1068. ===============================================================================
  1069.  
  1070. END OF LEVEL RUNES
  1071.  
  1072. ===============================================================================
  1073. */
  1074.  
  1075. void() sigil_touch =
  1076. {
  1077. local entity    stemp;
  1078. local float        best;
  1079.  
  1080.     if (other.classname != "player")
  1081.         return;
  1082.     if (other.health <= 0)
  1083.         return;
  1084.  
  1085.     centerprint (other, "You got the rune!");
  1086.  
  1087.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1088.     stuffcmd (other, "bf\n");
  1089.     self.solid = SOLID_NOT;
  1090.     self.model = string_null;
  1091.     serverflags = serverflags | (self.spawnflags & 15);
  1092.     self.classname = "";        // so rune doors won't find it
  1093.     
  1094.     activator = other;
  1095.     SUB_UseTargets();                // fire all targets / killtargets
  1096. };
  1097.  
  1098.  
  1099. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1100. End of level sigil, pick up to end episode and return to jrstart.
  1101. */
  1102.  
  1103. void() item_sigil =
  1104. {
  1105.     if (!self.spawnflags)
  1106.         objerror ("no spawnflags");
  1107.  
  1108.     precache_sound ("misc/runekey.wav");
  1109.     self.noise = "misc/runekey.wav";
  1110.  
  1111.     if (self.spawnflags & 1)
  1112.     {
  1113.         precache_model ("progs/end1.mdl");
  1114.         setmodel (self, "progs/end1.mdl");
  1115.     }
  1116.     if (self.spawnflags & 2)
  1117.     {
  1118.         precache_model2 ("progs/end2.mdl");
  1119.         setmodel (self, "progs/end2.mdl");
  1120.     }
  1121.     if (self.spawnflags & 4)
  1122.     {
  1123.         precache_model2 ("progs/end3.mdl");
  1124.         setmodel (self, "progs/end3.mdl");
  1125.     }
  1126.     if (self.spawnflags & 8)
  1127.     {
  1128.         precache_model2 ("progs/end4.mdl");
  1129.         setmodel (self, "progs/end4.mdl");
  1130.     }
  1131.     
  1132.     self.touch = sigil_touch;
  1133.     setsize (self, '-16 -16 -24', '16 16 32');
  1134.     StartItem ();
  1135. };
  1136.  
  1137. /*
  1138. ===============================================================================
  1139.  
  1140. POWERUPS
  1141.  
  1142. ===============================================================================
  1143. */
  1144.  
  1145. void() powerup_touch;
  1146.  
  1147.  
  1148. void() powerup_touch =
  1149. {
  1150. local entity    stemp;
  1151. local float        best;
  1152.  
  1153.     if (other.classname != "player")
  1154.         return;
  1155.     if (other.health <= 0)
  1156.         return;
  1157.  
  1158.     sprint (other, "You got the ");
  1159.     sprint (other, self.netname);
  1160.     sprint (other,"\n");
  1161.  
  1162.     if (deathmatch)
  1163.     {
  1164.         self.mdl = self.model;
  1165.         
  1166.         if ((self.classname == "item_artifact_invulnerability") ||
  1167.             (self.classname == "item_artifact_invisibility"))
  1168.             self.nextthink = time + 60*5;
  1169.         else
  1170.             self.nextthink = time + 60;
  1171.         
  1172.         self.think = SUB_regen;
  1173.     }    
  1174.  
  1175.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1176.     stuffcmd (other, "bf\n");
  1177.     self.solid = SOLID_NOT;
  1178.     other.items = other.items | self.items;
  1179.     self.model = string_null;
  1180.  
  1181. // do the apropriate action
  1182.     if (self.classname == "item_artifact_envirosuit")
  1183.     {
  1184.         other.rad_time = 1;
  1185.         other.radsuit_finished = time + 30;
  1186.     }
  1187.     
  1188.     if (self.classname == "item_artifact_invulnerability")
  1189.     {
  1190.         other.invincible_time = 1;
  1191.         other.invincible_finished = time + 30;
  1192.     }
  1193.     
  1194.     if (self.classname == "item_artifact_invisibility")
  1195.     {
  1196.         other.invisible_time = 1;
  1197.         other.invisible_finished = time + 30;
  1198.     }
  1199.  
  1200.     if (self.classname == "item_artifact_super_damage")
  1201.     {
  1202.         other.super_time = 1;
  1203.         other.super_damage_finished = time + 30;
  1204.     }    
  1205.  
  1206.     activator = other;
  1207.     SUB_UseTargets();                // fire all targets / killtargets
  1208. };
  1209.  
  1210.  
  1211.  
  1212. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1213. Player is invulnerable for 30 seconds
  1214. */
  1215. void() item_artifact_invulnerability =
  1216. {
  1217.     self.touch = powerup_touch;
  1218.  
  1219.     precache_model ("progs/invulner.mdl");
  1220.     precache_sound ("items/protect.wav");
  1221.     precache_sound ("items/protect2.wav");
  1222.     precache_sound ("items/protect3.wav");
  1223.     self.noise = "items/protect.wav";
  1224.     setmodel (self, "progs/invulner.mdl");
  1225.     self.netname = "Pentagram of Protection";
  1226.     self.items = IT_INVULNERABILITY;
  1227.     setsize (self, '-16 -16 -24', '16 16 32');
  1228.     StartItem ();
  1229. };
  1230.  
  1231. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1232. Player takes no damage from water or slime for 30 seconds
  1233. */
  1234. void() item_artifact_envirosuit =
  1235. {
  1236.     self.touch = powerup_touch;
  1237.  
  1238.     precache_model ("progs/suit.mdl");
  1239.     precache_sound ("items/suit.wav");
  1240.     precache_sound ("items/suit2.wav");
  1241.     self.noise = "items/suit.wav";
  1242.     setmodel (self, "progs/suit.mdl");
  1243.     self.netname = "Biosuit";
  1244.     self.items = IT_SUIT;
  1245.     setsize (self, '-16 -16 -24', '16 16 32');
  1246.     StartItem ();
  1247. };
  1248.  
  1249.  
  1250. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1251. Player is invisible for 30 seconds
  1252. */
  1253. void() item_artifact_invisibility =
  1254. {
  1255.     self.touch = powerup_touch;
  1256.  
  1257.     precache_model ("progs/invisibl.mdl");
  1258.     precache_sound ("items/inv1.wav");
  1259.     precache_sound ("items/inv2.wav");
  1260.     precache_sound ("items/inv3.wav");
  1261.     self.noise = "items/inv1.wav";
  1262.     setmodel (self, "progs/invisibl.mdl");
  1263.     self.netname = "Ring of Shadows";
  1264.     self.items = IT_INVISIBILITY;
  1265.     setsize (self, '-16 -16 -24', '16 16 32');
  1266.     StartItem ();
  1267. };
  1268.  
  1269.  
  1270. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1271. The next attack from the player will do 4x damage
  1272. */
  1273. void() item_artifact_super_damage =
  1274. {
  1275.     self.touch = powerup_touch;
  1276.  
  1277.     precache_model ("progs/quaddama.mdl");
  1278.     precache_sound ("items/damage.wav");
  1279.     precache_sound ("items/damage2.wav");
  1280.     precache_sound ("items/damage3.wav");
  1281.     self.noise = "items/damage.wav";
  1282.     setmodel (self, "progs/quaddama.mdl");
  1283.     self.netname = "Quad Damage";
  1284.     self.items = IT_QUAD;
  1285.     setsize (self, '-16 -16 -24', '16 16 32');
  1286.     StartItem ();
  1287. };
  1288.  
  1289.  
  1290.  
  1291. /*
  1292. ===============================================================================
  1293.  
  1294. PLAYER BACKPACKS
  1295.  
  1296. ===============================================================================
  1297. */
  1298.  
  1299. void() BackpackTouch =
  1300. {
  1301.     local string    s;
  1302.     local    float    best;
  1303.     local        entity    stemp;
  1304.     
  1305.     if (other.classname != "player")
  1306.         return;
  1307.     if (other.health <= 0)
  1308.         return;
  1309.         
  1310. // if the player was using his best weapon, change up to the new one if better        
  1311.     stemp = self;
  1312.     self = other;
  1313.     best = W_BestWeapon();
  1314.     self = stemp;
  1315.  
  1316. // change weapons
  1317.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1318.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1319.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1320.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1321.  
  1322.     other.items = other.items | self.items;
  1323.     
  1324.     bound_other_ammo ();
  1325.  
  1326.     sprint (other, "You get ");
  1327.  
  1328.     if (self.ammo_shells)
  1329.     {
  1330.         s = ftos(self.ammo_shells);
  1331.         sprint (other, s);
  1332.         sprint (other, " shells  ");
  1333.     }
  1334.     if (self.ammo_nails)
  1335.     {
  1336.         s = ftos(self.ammo_nails);
  1337.         sprint (other, s);
  1338.         sprint (other, " nails ");
  1339.     }
  1340.     if (self.ammo_rockets)
  1341.     {
  1342.         s = ftos(self.ammo_rockets);
  1343.         sprint (other, s);
  1344.         sprint (other, " rockets  ");
  1345.     }
  1346.     if (self.ammo_cells)
  1347.     {
  1348.         s = ftos(self.ammo_cells);
  1349.         sprint (other, s);
  1350.         sprint (other, " cells  ");
  1351.     }
  1352.     
  1353.     sprint (other, "\n");
  1354. // backpack touch sound
  1355.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1356.     stuffcmd (other, "bf\n");
  1357.  
  1358. // change to a better weapon if appropriate
  1359.     if ( other.weapon == best )
  1360.     {
  1361.         stemp = self;
  1362.         self = other;
  1363.         self.weapon = W_BestWeapon();
  1364.         self = stemp;
  1365.     }
  1366.  
  1367.     
  1368.     remove(self);
  1369.     
  1370.     self = other;
  1371.     W_SetCurrentAmmo ();
  1372. };
  1373.  
  1374. /*
  1375. ===============
  1376. DropBackpack
  1377. ===============
  1378. */
  1379. void() DropBackpack =
  1380. {
  1381.     local entity    item;
  1382.  
  1383.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1384.         return;    // nothing in it
  1385.  
  1386.     item = spawn();
  1387.     item.origin = self.origin - '0 0 24';
  1388.     
  1389.     item.items = self.weapon;
  1390.  
  1391.     item.ammo_shells = self.ammo_shells;
  1392.     item.ammo_nails = self.ammo_nails;
  1393.     item.ammo_rockets = self.ammo_rockets;
  1394.     item.ammo_cells = self.ammo_cells;
  1395.  
  1396.     item.velocity_z = 300;
  1397.     item.velocity_x = -100 + (random() * 200);
  1398.     item.velocity_y = -100 + (random() * 200);
  1399.     
  1400.     item.flags = FL_ITEM;
  1401.     item.solid = SOLID_TRIGGER;
  1402.     item.movetype = MOVETYPE_TOSS;
  1403.     setmodel (item, "progs/backpack.mdl");
  1404.     setsize (item, '-16 -16 0', '16 16 56');
  1405.     item.touch = BackpackTouch;
  1406.     
  1407.     item.nextthink = time + 120;    // remove after 2 minutes
  1408.     item.think = SUB_Remove;
  1409. };
  1410.